package report

import (
	"context"
	"fmt"
	"git.mycaigou.com/gfyx/common/tenant_db"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/utils"
	pb "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/clue"
	"gorm.io/gorm"
)

type GfyxReportRepos struct {
	tenant_db.TenantDB
}

func NewGfyxReportRepos() GfyxReportReposIface {
	return &GfyxReportRepos{}
}

func (r *GfyxReportRepos) GetReport(ctx context.Context, reportId string) (*GfyxReport, error) {
	gfyxReport := GfyxReport{}
	db := r.GetTenantDB(ctx).
		Where("is_deleted = 0 and uid = ? ", reportId).
		Find(&gfyxReport)
	if db.Error != nil && db.Error != gorm.ErrRecordNotFound {
		return nil, db.Error
	}
	return &gfyxReport, nil
}

func (r *GfyxReportRepos) GetReportByCondition(ctx context.Context, condition map[string]interface{}) (*GfyxReport, error) {
	gfyxReport := &GfyxReport{}
	err := r.GetTenantDB(ctx).
		Where(condition).Where("is_deleted = 0").
		Find(gfyxReport).
		Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, err
	}
	if err != nil && err == gorm.ErrRecordNotFound {
		fmt.Println("empty data")
		return nil, nil
	}
	return gfyxReport, nil
}

func (r *GfyxReportRepos) ReportCount(ctx context.Context, condition map[string]interface{}) (int64, error) {
	var cnt int64
	err := r.GetTenantDB(ctx).Table(GfyxReport{}.TableName() + " as a").Where(condition).Count(&cnt).Error
	if err != nil {
		return 0, err
	}
	return cnt, nil
}

func (r *GfyxReportRepos) buildWhereByDto(db *gorm.DB, request *pb.GetReportListRequest) *gorm.DB {
	db = db.Where("c.is_deleted = ?", 0)
	if request.GetResponsiblePersonGuid() != "" {
		db = db.Where("c.responsible_person_guid = ?", request.GetResponsiblePersonGuid())
	}
	if request.GetProjectProvinceCode() != "" && request.GetProjectProvinceCode() != "0" {
		db = db.Where("c.project_province_code = ?", request.GetProjectProvinceCode())
	}
	if request.GetProjectCityCode() != "" {
		db = db.Where("c.project_city_code = ?", request.GetProjectCityCode())
	}
	if request.GetCompanyProvinceCode() != "" {
		db = db.Where("c.company_province_code = ?", request.GetCompanyProvinceCode())
	}
	if request.GetCompanyCityCode() != "" {
		db = db.Where("c.company_city_code = ?", request.GetCompanyCityCode())
	}
	if request.GetSubmitStartTime() != "" && request.GetSubmitEndTime() != "" {
		db = db.Where("c.created_on >= ? AND c.created_on <= ?", request.GetSubmitStartTime(), request.GetSubmitEndTime())
	}
	if request.GetFollowStatus() > 0 {
		db = db.Where("c.follow_status = ?", request.GetFollowStatus())
	}

	if request.GetKeyword() != "" {
		db = db.Where("c.project_title LIKE ? or c.company_name LIKE ?", "%"+request.GetKeyword()+"%", "%"+request.GetKeyword()+"%")
	}

	return db
}

func (r *GfyxReportRepos) GetMyReportListCount(ctx context.Context, request *pb.GetReportListRequest) (int64, error) {
	var total int64
	db := r.GetTenantDB(ctx).Model(&GfyxReport{})
	db = db.Table("gfyx_report c")
	db = r.buildWhereByDto(db, request)
	db.Count(&total)
	if db.Error != nil {
		return 0, db.Error
	}

	return total, nil
}

// TestTenantDbEnable 测试租户db是否可用
func (r *GfyxReportRepos) TestTenantDbEnable(ctx context.Context, request *pb.TestTenantDbEnableRequest) (int64, error) {
	// 测试对象
	type Advancesearchfield struct {
		AdvanceSearchFieldGUID string `gorm:"column:AdvanceSearchFieldGUID;primaryKey"`
		ActionCode             string `gorm:"column:ActionCode"`
		ActionOptions          string `gorm:"column:ActionOptions;type:longtext"`
	}
	db := r.GetTenantDB(ctx)
	advancesearchfield := &Advancesearchfield{}
	err := db.Table("advancesearchfield").First(&advancesearchfield).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return 0, err
	}
	return 1, nil
}

func (r *GfyxReportRepos) GetMyReportList(ctx context.Context, request *pb.GetReportListRequest) ([]*GfyxReport, error) {
	reportList := make([]*GfyxReport, 0)
	db := r.GetTenantDB(ctx)
	db = db.Table("gfyx_report c")
	db = r.buildWhereByDto(db, request)
	db.Order("c.created_on desc").
		Limit(int(request.GetPageSize())).
		Offset(int((request.GetPage() - 1) * request.GetPageSize())).
		Find(&reportList)

	if db.Error != nil && db.Error != gorm.ErrRecordNotFound {
		return nil, db.Error
	}

	return reportList, nil
}

func (r *GfyxReportRepos) GetReportList(ctx context.Context, condition map[string]interface{}, pageInfo *utils.PageInfo) (int64, []*GfyxReport, error) {
	// 传入所在用户的guid 条件查询即可
	reportList := make([]*GfyxReport, 0)
	var count int64
	db := r.GetTenantDB(ctx).Table(GfyxReport{}.TableName())
	if _, ok := condition["user_ids"]; ok {
		db.Where("responsible_person_guid in ?", condition["user_ids"])
		delete(condition, "user_ids")
	}
	if _, ok1 := condition["keyword"]; ok1 {
		keyword := fmt.Sprintf("%%%s%%", condition["keyword"])
		db = db.Where("project_title LIKE ? or company_name LIKE ?", keyword, keyword)
		delete(condition, "keyword")
	}
	_, ok2 := condition["created_on_start"]
	_, ok3 := condition["created_on_end"]
	if ok2 && ok3 {
		db = db.Where("created_on >=? AND created_on <=?", condition["created_on_start"], condition["created_on_end"])
		delete(condition, "created_on_start")
		delete(condition, "created_on_end")
	}
	db = db.Where(condition)
	err := db.Count(&count).Error
	if err != nil {
		return 0, nil, err
	}

	if pageInfo != nil && pageInfo.Page > 0 && pageInfo.PageSize > 0 {
		db = db.Offset((pageInfo.Page - 1) * pageInfo.PageSize).Limit(pageInfo.PageSize)
	}
	if err = db.Find(&reportList).Order("created_on desc").Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return 0, nil, nil
		}
		return 0, nil, err
	}
	return count, reportList, nil
}

func (r *GfyxReportRepos) SaveReport(ctx context.Context, report *GfyxReport) (int64, error) {
	db := r.GetTenantDB(ctx).Save(report)
	if db.Error != nil {
		return 0, db.Error
	}
	return db.RowsAffected, nil
}

func (r *GfyxReportRepos) GetUserList(ctx context.Context) ([]*ResponsibleUser, error) {
	users := make([]*ResponsibleUser, 0)
	db := r.GetTenantDB(ctx)
	db = db.Table("gfyx_report c").
		Select("m.uid as UserGUID,m.name as UserName").
		Joins("inner join gfyx_user as m on c.responsible_person_guid = m.uid").
		Group("m.uid,m.name").Scan(&users)
	if db.Error != nil && db.Error != gorm.ErrRecordNotFound {
		return nil, db.Error
	}
	return users, nil
}
